package com.zkyc.framework.website.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.zkyc.framework.common.constant.NumberConstant;
import com.zkyc.framework.common.exception.ResultCode;
import com.zkyc.framework.common.mapper.ApproveMapper;
import com.zkyc.framework.common.mapper.PiMapper;
import com.zkyc.framework.common.pojo.Approve;
import com.zkyc.framework.common.pojo.Center;
import com.zkyc.framework.common.pojo.Pi;
import com.zkyc.framework.common.pojo.WebContent;
import com.zkyc.framework.common.service.RestTemplateService;
import com.zkyc.framework.common.utils.WebsiteUtil;
import com.zkyc.framework.common.vo.ResultVO;
import com.zkyc.framework.common.vo.website.UploadVo;
import com.zkyc.framework.website.client.FileClient;
import com.zkyc.framework.common.mapper.CenterMapper;
import com.zkyc.framework.website.service.CenterService;
import com.zkyc.framework.website.util.TokenUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;


/**
 * (Center)表服务实现类
 *
 * @author libingchuan
 * @since 2022-05-25 19:21:50
 */
@Slf4j
@Service("centerService")
@RefreshScope
public class CenterServiceImpl implements CenterService {
    @Resource
    private CenterMapper centerMapper;
    @Resource
    private PiMapper piMapper;

    @Resource
    private ApproveMapper approveMapper;

    @Autowired
    private FileClient fileClient;

    @Value("${zjlab.cookie}")
    private String cookies;

    public static final String PI_URL = "https://portal.zhejianglab.com/api/portal/column/article/page?userCode={userCode}&current=1&size=30&requestSource=xxx";
    public static final String PI_INFO_URL = "https://portal.zhejianglab.com/api/portal/user/portrait/info?home_page_user_code={userCode}";
    public static final String PI_BASIC = "http://gateway.dmind.zhejianglab.com/rest/davinci-0.3-rc/api/v3/zj/34/fetchData";
    public static final String PI_RESEARCH = "http://gateway.dmind.zhejianglab.com/rest/davinci-0.3-rc/api/v3/zj/35/fetchData";


    @Autowired
    RestTemplateService restTemplateService;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Center queryById(Integer id) {
        Center center = centerMapper.selectById(id);
        String websiteId = WebsiteUtil.getWebsiteId();
        if (center.getAttachementUrl() != null) {
            JSONArray jsonArray = JSONArray.parseArray(center.getAttachementUrl());
            center.setAttachementUrlJson(jsonArray);
        } else {
            center.setAttachementUrlJson(new JSONArray());
        }
        if (center.getPi() != null) {
            try {
                List<Pi> piList = new ArrayList<>();
                String[] pis = center.getPi().split(",");
                for (String s : pis) {
                    Pi pi = centerMapper.findCenterByUserCode(s, websiteId);
                    if (pi != null) {
                        if (StringUtils.isNotBlank(pi.getPiInformation())) {
                            JSONArray jsonArray = JSONArray.parseArray(pi.getPiInformation());
                            pi.setPiInformationJSONArray(jsonArray);
                        } else {
                            pi.setPiInformationJSONArray(new JSONArray());
                        }
                        piList.add(pi);
                        center.setPiList(piList);
                    }
                }
            } catch (Exception e) {
                center.setPiList(null);
            }
        }
        return center;
    }

    /**
     * 新增数据
     *
     * @param center 实例对象
     * @return 实例对象
     */
    @Override
    public ResultVO insert(Center center) {
        if (center == null) {
            return ResultVO.fail(ResultCode.PARAM_INVALID);
        }
        if (!checkDuplicate(center)) {
            return ResultVO.fail(ResultCode.CENTER_DUPLICATION);
        }
        String userId = TokenUserUtil.getCurrentUserId();
        center.setOperateUserId(userId);
        List<Pi> piList = center.getPiList();
        List<String> piIdList = piList.stream().map(Pi::getUserCode).collect(Collectors.toList());
        if (piList.size() == 0) {
            return ResultVO.fail(ResultCode.PI_NULL);
        } else {
            String pi = StringUtils.join(piIdList, ",");
            center.setPi(pi);
        }
        centerMapper.insert(center);
        try {
            //PITask(center);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVO.fail(e.toString());
        }
        return ResultVO.success(ResultCode.SUCCESS);
    }

    private boolean checkDuplicate(Center center) {
        if (center.getCenterName() != null) {
            QueryWrapper<Center> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("center_name", center.getCenterName());
            if (center.getId() != null) {
                queryWrapper.ne("id", center.getId());
            }
            List<Center> centers = centerMapper.selectList(queryWrapper);
            if (centers.size() > 0) {
                return false;
            }
        }
        return true;
    }


    /**
     * 修改数据
     *
     * @param center 实例对象
     * @return 实例对象
     */
    @Override
    public ResultVO update(Center center) {
        if (center == null && center.getId() == null) {
            return ResultVO.fail(ResultCode.PARAM_INVALID);
        }
        if (queryById(center.getId()) == null) {
            return ResultVO.fail(ResultCode.SERVE_ERROR);
        }
        if (!checkDuplicate(center)) {
            return ResultVO.fail(ResultCode.CENTER_DUPLICATION);
        }
        List<Pi> piList = center.getPiList();
        List<String> piIdList = piList.stream().map(Pi::getUserCode).collect(Collectors.toList());
        if (piList.size() == 0) {
            return ResultVO.fail(ResultCode.PI_NULL);
        } else {
            String pi = StringUtils.join(piIdList, ",");
            center.setPi(pi);
        }
        String userId = TokenUserUtil.getCurrentUserId();
        center.setOperateUserId(userId);
        centerMapper.updateById(center);
        try {
            //PITask(center);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVO.fail(e.toString());
        }
        return ResultVO.success(ResultCode.SUCCESS);
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public ResultVO deleteById(Integer id) {
        if (id == null) {
            return ResultVO.fail(ResultCode.PARAM_INVALID);
        }
        Center center = queryById(id);
        if (center == null) {
            return ResultVO.fail(ResultCode.SERVE_ERROR);
        }
        centerMapper.deleteById(id);
        return ResultVO.data(center.getCenterName());
    }


    private void PITask(Center center) {
        if (center.getPi() != null) {
            String pis = center.getPi();
            String[] splitPis = pis.split(",");
            for (String splitPi : splitPis) {
                HashMap map = new HashMap();
                map.put("userCode", splitPi);
                insertToPi(map);
            }
        }
    }

    @Async
    public void insertToPi(HashMap<String, String> map) {
        JSONArray records = getObjects(map);
        addPi(map, records);
    }

    private ResultVO addPi(HashMap<String, String> map, JSONArray records) {
        QueryWrapper<Pi> queryWrapper = new QueryWrapper<>();
        if (map.get("userCode") != null) {
            String userCode = map.get("userCode");
            queryWrapper.eq("user_code", userCode);
            queryWrapper.eq("website_id", WebsiteUtil.getWebsiteId());
            Pi pi = piMapper.selectOne(queryWrapper);
            if (pi == null) {
                pi = new Pi();
                pi.setIsVerified(NumberConstant.NUMBER_0);
                pi.setUserCode(userCode);
                pi.setPiInformation(records.toString().replaceAll("https://file.zhejianglab.com", "https://www.zhejianglab.com"));
                int size = records.size();
                pi.setName(records.getJSONObject(NumberConstant.NUMBER_0).get("name").toString());
                pi.setWebsiteId(WebsiteUtil.getWebsiteId());
                pi.setOrganizationTwo(records.getJSONObject(NumberConstant.NUMBER_0).getOrDefault("dept_name", " ").toString());
                pi.setOrganizationOne(records.getJSONObject(NumberConstant.NUMBER_0).getOrDefault("ssbm", " ").toString());
                piMapper.insert(pi);
                log.info("pi添加成功:{}", pi);
            } else {
                int size = records.size();
                pi.setName(records.getJSONObject(NumberConstant.NUMBER_0).get("name").toString());
                pi.setPiInformation(records.toString().replaceAll("https://file.zhejianglab.com", "https://www.zhejianglab.com"));
                piMapper.updateById(pi);
                log.info("pi更新成功:{}", pi);
            }
            return ResultVO.data(pi);
        }
        return ResultVO.fail(ResultCode.FAILURE);
    }

    private JSONArray getObjects(HashMap<String, String> map) {
        JSONObject PIJsonObject = restTemplateService.sendRequest(PI_URL, cookies, map);
        JSONObject PIInfoJsonObject = restTemplateService.sendRequest(PI_INFO_URL, cookies, map);
        JSONObject data = PIJsonObject.getJSONObject("data");
        String name = (String) PIInfoJsonObject.getJSONObject("data").get("name");
        if (name != null) {
            JSONObject piInfoJsonObject = PIInfoJsonObject.getJSONObject("data");
            setPhoto(piInfoJsonObject);
            data.getJSONArray("records").add(piInfoJsonObject);
        }
        return data.getJSONArray("records");
    }

    public ResultVO checkPi(String userCode) {
        HashMap map = new HashMap();
        map.put("userCode", userCode);
        JSONArray records = null;
        try {
            records = getObjects(map);
        } catch (Exception e) {
            e.printStackTrace();
            if (e.toString().contains("主页拥有者信息不存在")) {
                return ResultVO.fail("主页拥有者信息不存在");
            }
            return ResultVO.fail(e.toString());
        }
        if (records.size() == 0) {
            return ResultVO.fail(ResultCode.PI_ILLEGAL);
        }
        return addPi(map, records);
    }

    @Override
    public ResultVO addPi(String userCode) {
        //设置userCodeMap,已有addPi方法不需重写
        HashMap<String, String> userCodeMap = new HashMap();
        userCodeMap.put("userCode", userCode);
        JSONObject userCodeJSON = new JSONObject();
        userCodeJSON.put("user_code", userCode);
        //调用PI_BASIC接口
        String piBasicString = HttpRequest.get(PI_BASIC)
                .form("user_code", userCode)
                .execute().body();
        //调用PI_RESEARCH接口
        String piBasicResearch = HttpRequest.get(PI_RESEARCH)
                .form("user_code", userCode)
                .execute().body();
        //处理数据
        JSONObject piBasicJsonOriginal = JSONObject.parseObject(piBasicString);
        JSONObject piResearchJsonOriginal = JSONObject.parseObject(piBasicResearch);
        JSONArray piBasicArray = piBasicJsonOriginal.getJSONObject("payload").getJSONArray("resultList");
        JSONArray piResearchArray = piResearchJsonOriginal.getJSONObject("payload").getJSONArray("resultList");
        if (piBasicArray.size() > 0) {
            JSONObject piBasicJSONObject = piBasicArray.getJSONObject(NumberConstant.NUMBER_0);
            //下载头像存储至Minio
            //setPhoto(piBasicJSONObject);
            //JSONObject piResearchJSONObject = piResearchArray.getJSONObject(NumberConstant.NUMBER_0);
            piBasicArray.add(piResearchArray);
        } else {
            return ResultVO.fail("主页拥有者信息不存在");
        }
        return addPi(userCodeMap, piBasicArray);
    }

    @Override
    public ResultVO deletePi(Integer id, String userCode) {
        Pi pi = piMapper.selectOne(new LambdaQueryWrapper<Pi>().eq(Pi::getUserCode, userCode).eq(Pi::getWebsiteId, WebsiteUtil.getWebsiteId()));
        if (pi != null) {
            Integer piId = pi.getId();
            piMapper.deleteById(piId);
            Approve approve = approveMapper.selectOne(new LambdaQueryWrapper<Approve>().eq(Approve::getPid, piId).eq(Approve::getType, 2));
            if (approve != null) {
                approveMapper.deleteById(approve);
            }
            Center center = centerMapper.selectById(id);
            String centerPi = center.getPi();
            if (centerPi.startsWith(userCode)) {
                centerPi = centerPi.replace(userCode, "");
            } else {
                centerPi = centerPi.replace("," + userCode, "");
            }
            center.setPi(centerPi);
            centerMapper.updateById(center);
        }
        return ResultVO.data(ResultCode.SUCCESS);
    }

    @Override
    public ResultVO submit(Integer id, Integer centerId) {
        Approve approve = approveMapper.selectOne(new LambdaQueryWrapper<Approve>().eq(Approve::getPid, id).eq(Approve::getType, 2));
        if (approve != null) {
            //已驳回的要进行重置
            if (approve.getStatus() == 2) {
                approveMapper.deleteById(approve);
            } else {
                return ResultVO.fail(ResultCode.APPROVE_DUPLICATION);
            }
        }
        Pi pi = piMapper.selectById(id);
        Center center = null;
        try {
            center = centerMapper.selectOne(new LambdaQueryWrapper<Center>().in(Center::getPi, pi.getUserCode()).eq(Center::getId, centerId));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultVO.fail(ResultCode.PI_DUPLICATION);
        }
        Center center1 = centerMapper.selectById(centerId);
        if (!center1.getCenterName().equals(pi.getOrganizationTwo())) {
            return ResultVO.fail(ResultCode.PI_NOT_EXIST);
        }
        pi.setIsVerified(3);
        piMapper.updateById(pi);
        List<String> piList = new ArrayList<>(Arrays.asList(center1.getPi().split(",")));
        piList.add(pi.getUserCode());
        center1.setPi(StringUtils.join(piList, ","));
        centerMapper.updateById(center1);
        Approve approve1 = new Approve();
        approve1.setCenterId(center1.getId());
        approve1.setLevel(1);
        approve1.setType(2);
        approve1.setCreatedBy(pi.getCreateUserName());
        approve1.setStatus(0);
        approve1.setPid(pi.getId());
        approveMapper.insert(approve1);
        return ResultVO.success(ResultCode.SUCCESS);
    }

    private void setPhoto(JSONObject piBasicJSONObject) {
        if (piBasicJSONObject.get("photo") != null) {
            String photo = piBasicJSONObject.get("photo").toString();
            try {
                UploadVo uploadVo = fileClient.uploadByUrl(photo, StringPool.ONE);
                JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(uploadVo.getData()));
                piBasicJSONObject.put("photo", jsonObject.get("url"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public ResultVO getCenterInfo(Integer id, Integer isVerified) {
        if (id == null) {
            return ResultVO.fail(ResultCode.PARAM_INVALID);
        }
        Center center = centerMapper.selectById(id);
        String[] split = center.getPi().split(",");
        List<String> piCodeList = Arrays.asList(split);
        ArrayList<Pi> piList = new ArrayList<>();
        Integer websiteId = Integer.valueOf(WebsiteUtil.getWebsiteId());
        piCodeList.forEach(s -> {
            LambdaQueryWrapper<Pi> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Pi::getUserCode, s).eq(Pi::getWebsiteId, websiteId);
            if (isVerified != null) {
                wrapper.eq(Pi::getIsVerified, isVerified);
            }
            Pi pi = piMapper.selectOne(wrapper);
            if (pi != null) {
                piList.add(pi);
            }
        });
        center.setPiList(piList);
        return ResultVO.data(center);
    }
}
